// WLock.cpp: implementation of the WLock class.
//
//////////////////////////////////////////////////////////////////////
#include "autolock.h"

#include "assert.h"
#include "basetype.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#ifdef _WIN32

skylock::skylock():
	m_nCount( 0 )
{
	InitializeCriticalSection( &m_Lock );
}

skylock::~skylock()
{
	DeleteCriticalSection( &m_Lock );
}

VOID skylock::lock()
{
	EnterCriticalSection( &m_Lock );
//	if( ++m_nCount > 1 )
//		LeaveCriticalSection( &m_Lock );
}

VOID skylock::unlock()
{
//	if( --m_nCount == 0 )
		LeaveCriticalSection( &m_Lock );
}

bool skylock::trylock()
{
	if( !TryEnterCriticalSection( &m_Lock ))
		return false;
//	if( ++m_nCount > 1 )
//		LeaveCriticalSection( &m_Lock );
	return true;
}

#else

skylock::skylock():
	m_nCount( 0 )
{
	int rc;
	const pthread_mutexattr_t attr = { PTHREAD_MUTEX_RECURSIVE_NP };
	rc = pthread_mutex_init( &m_Lock,&attr );
}

skylock::~skylock()
{
	int rc = 0;
	rc = pthread_mutex_destroy( &m_Lock );
}

VOID skylock::lock()
{
	int rc = pthread_mutex_lock( &m_Lock );
	assert( rc == 0 );
	if( rc != 0 )
		return;
	if( ++m_nCount > 1 ){
		rc = pthread_mutex_unlock( &m_Lock );
		assert( rc == 0 );
	}
}

VOID skylock::unlock()
{
	if( --m_nCount == 0 ){
		int rc = 0;
		rc = pthread_mutex_unlock( &m_Lock );
		assert( rc == 0 );
	}
}

BOOL skylock::trylock()
{
	int rc = pthread_mutex_trylock( &m_Lock );
	BOOL bResult = ( rc == 0 );
	if( !bResult ){
		assert( rc == EBUSY );
	}else if( ++m_nCount > 1 ){
		rc = pthread_mutex_unlock( &m_Lock );
		assert( rc == 0 );
	}
	return bResult;
}

#endif

auto_lock::auto_lock( skylock* pLock ):m_pLock( pLock )
{
	if( m_pLock )
		m_pLock->lock();
}

auto_lock::~auto_lock()
{
	if( m_pLock )
		m_pLock->unlock();
}
